package io.snow.mybatis.core.exception;

import io.snow.mybatis.core.common.R;
import io.snow.mybatis.core.common.Result;
import io.snow.mybatis.core.common.ResultCode;
import io.snow.mybatis.core.common.SystemCodeEnum;
import io.snow.mybatis.core.entity.UserExtraInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.NoHandlerFoundException;
import javax.servlet.ServletException;

@RestControllerAdvice
@Slf4j
public class ExceptionHandlerAdvice {

    @ExceptionHandler(value = Exception.class)
    public Result defaultException(Exception ex){
        log.error("默认异常需要处理", ex);
        if (ex instanceof ResultCode) {
            return R.error( ((ResultCode) ex).getCode(), ((ResultCode) ex).getMsg() );
        }
        return Result.error(SystemCodeEnum.SYSTEM_ERROR);
    }

    @ExceptionHandler(value = AuthException.class)
    public Result authException() {
        return Result.noAuth();
    }

    @ExceptionHandler(value = NoLoginException.class)
    public Result<UserExtraInfo> noLoginException(NoLoginException ex) {
        Result<UserExtraInfo> result = Result.error(SystemCodeEnum.SYSTEM_NOT_LOGIN);
        result.setData(ex.getUserInfo());
        return result;
    }

    @ExceptionHandler(value = HttpRequestMethodNotSupportedException.class)
    public Result methodNotSupportedException(HttpRequestMethodNotSupportedException ex) {
        log.error("方法请求错误", ex);
        return Result.noAuth();
    }

    @ExceptionHandler(value = ServletException.class)
    public Result servletException(ServletException ex) {
        if (ex instanceof NoHandlerFoundException) {
            log.error("请求路径未找到：", ((NoHandlerFoundException) ex ).getRequestURL());
        }
        log.error("ServletException:", ex);
        return Result.error(SystemCodeEnum.SYSTEM_ERROR);
    }

    @ExceptionHandler(value = BindException.class)
    public Result validException(BindException ex) {
        log.error("BindExcption:", ex);
        if (ex.getGlobalError() != null) {
            return Result.error(SystemCodeEnum.SYSTEM_NO_VALID, ex.getGlobalError().getDefaultMessage());
        } else if (ex.getFieldError() != null) {
            return Result.error(SystemCodeEnum.SYSTEM_NO_VALID, ex.getFieldError().getDefaultMessage());
        } else {
            return Result.error(SystemCodeEnum.SYSTEM_NO_VALID);
        }
    }

    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    public Result argumentNotValidException(MethodArgumentNotValidException ex) {
        log.error("MethodArgumentNotValidException:", ex);
        BindingResult bindingResult = ex.getBindingResult();
        if (bindingResult.getGlobalError() != null) {
            return Result.error(SystemCodeEnum.SYSTEM_NO_VALID, bindingResult.getGlobalError().getDefaultMessage());
        } else if (bindingResult.getFieldError() != null) {
            return Result.error(SystemCodeEnum.SYSTEM_NO_VALID, bindingResult.getFieldError().getDefaultMessage());
        } else {
            return Result.error(SystemCodeEnum.SYSTEM_NO_VALID);
        }
    }

}